#include "vn/TimeSpan.h"

void TimeSpanTest() {
	// TESTCASE(constructors & properties)
	{
		int miliseconds	= 999;
		int hours		= 1;
		int minutes		= 2;
		int seconds		= 3;
		int days		= 4;
		
		// ctor 1
		const TimeSpan a;
		assert(a.data == 0);

		const TimeSpan b(miliseconds);
		assert(b.data == miliseconds);

		// ctor 2
		const TimeSpan c(hours, minutes, seconds);
		assert(c.GetDays() == 0);
		assert(c.GetHours() == hours);
		assert(c.GetMinutes() == minutes);
		assert(c.GetSeconds() == seconds);
		assert(c.GetMilliseconds() == 0);

		// ctor 3
		const TimeSpan d(days, hours, minutes, seconds);
		assert(d.GetDays() == days);
		assert(d.GetHours() == hours);
		assert(d.GetMinutes() == minutes);
		assert(d.GetSeconds() == seconds);
		assert(d.GetMilliseconds() == 0);

		const TimeSpan e(days, hours, minutes, seconds, miliseconds);
		assert(e.GetDays() == days);
		assert(e.GetHours() == hours);
		assert(e.GetMinutes() == minutes);
		assert(e.GetSeconds() == seconds);
		assert(e.GetMilliseconds() == miliseconds);
	}

	// TESTCASE(length unit)
	{
		//ctor 4
		const TimeSpan a(-1.5, TimeSpan::Days);
		assert(a == TimeSpan(-1, -12, 0, 0, 0));

		const TimeSpan b(1.5, TimeSpan::Hours);
		assert(b == TimeSpan(0, 1, 30, 0, 0));

		const TimeSpan c(1.5, TimeSpan::Minutes);
		assert(c == TimeSpan(0, 0, 1, 30, 0));

		const TimeSpan d(1.5, TimeSpan::Seconds);
		assert(d == TimeSpan(0, 0, 0, 1, 500));

		const TimeSpan e(2.8, TimeSpan::Miliseconds);
		assert(e == TimeSpan(0, 0, 0, 0, 2));		// why not 3?
	}

	// Properties of positive value
	{
		const TimeSpan a(1, 12, 30, 30, 500);

		assert(a.GetDays() == 1);
		assert(a.GetHours() == 12);
		assert(a.GetMinutes() == 30);
		assert(a.GetSeconds() == 30);
		assert(a.GetMilliseconds() == 500);

		double days				= a.GetTotalDays();
		double hours			= a.GetTotalHours();
		double minutes			= a.GetTotalMinutes();
		double seconds			= a.GetTotalSeconds();
		double miliseconds		= a.GetTotalMilliseconds();
		assert(days    * 24		== hours);
		assert(hours   * 60		== minutes);
		assert(minutes * 60		== seconds);
		assert(seconds * 1000	== miliseconds);
	}

	// Properties of nagative value
	{
		TimeSpan a(1, 12, 30, 30, 500);
		a = -a;

		assert(a.GetDays() == -1);
		assert(a.GetHours() == -12);
		assert(a.GetMinutes() == -30);
		assert(a.GetSeconds() == -30);
		assert(a.GetMilliseconds() == -500);

		double days				= a.GetTotalDays();
		double hours			= a.GetTotalHours();
		double minutes			= a.GetTotalMinutes();
		double seconds			= a.GetTotalSeconds();
		double miliseconds		= a.GetTotalMilliseconds();
		assert(days    * 24		== hours);
		assert(hours   * 60		== minutes);
		assert(minutes * 60		== seconds);
		assert(seconds * 1000	== miliseconds);
	}

	// operators a + b, a - b, -a
	{
		const TimeSpan	a(1, 12, 30, 30, 500);
		const TimeSpan	b(2, 13, 31, 31, 501);
		const TimeSpan	one(1, 1,   1,  1,   1);

		assert(b - a ==  one);
		assert(a - b == -one);
		assert(a + (-a) == TimeSpan(0));		
	}

	// comparators return true
	{
		const TimeSpan	a(1, 12, 30, 30, 500);
		const TimeSpan	b(2, 13, 31, 31, 501);

		assert(a == a);

		assert(a != b);

		assert(a < b);

		assert(a <= a);
		assert(a <= b);

		assert(b > a);

		assert(b >= b);
		assert(b >= a);
	}

	// comparators return false
	{
		const TimeSpan	a(1, 12, 30, 30, 500);
		const TimeSpan	b(2, 13, 31, 31, 501);
		assert( !(a == b) );
		assert( !(a != a) );
		assert( !(b < a) );
		assert( !(b <= a) );
		assert( !(a > b) );
		assert( !(a >= b) );
	}

	// TimeSpan from real number.
	{
		// TimeSpan a = TimeSpan::FromDays(1.5)
		// TimeSpan b = TimeSpan::FromHours(1.5)
	}
}
